/** @file    WidgetMethodCaller.cpp
 *  @author  Alessandro Polo
 *  @version $Id: WidgetMethodCaller.cpp 2544 2010-05-26 02:35:43Z alex $
 *  @brief
 * File containing methods for the wosh::gui::WidgetMethodCaller class.
 * The header for this class can be found in WidgetMethodCaller.h, check that file
 * for class description.
 ****************************************************************************/
/* Copyright (c) 2007-2010, WOSH - Wide Open Smart Home 
 * by Alessandro Polo - OpenSmartHome.com
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the OpenSmartHome.com WOSH nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY Alessandro Polo ''AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL Alessandro Polo BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 ****************************************************************************/

 #include "WidgetMethodCaller.h"
 #include "ui_WidgetMethodCaller.h"

 #include <core/Request.h>
 #include <core/Response.h>
 #include <core/MethodsCommon.h>


using namespace std;
namespace wosh {
 namespace gui {

//////////////////////////////////////////////////////////////////////////////////////////////////////////////

WidgetMethodCaller::WidgetMethodCaller(QWidget *parent) : QWidget(parent), IWidget()
 {
	this->m_ui = new Ui::WidgetMethodCaller();
	this->m_ui->setupUi(this);

	this->requestArgument = NULL;
	this->responseData = NULL;


	connect(this->m_ui->btnCall, SIGNAL(clicked()), this, SLOT(btnCall_clicked()));

	connect(this->m_ui->cmbRequestArgumentType, SIGNAL(activated(const QString&)), this, SLOT(cmbRequestArgumentType_activated(const QString&)));

	this->m_ui->cmbRequestArgumentType->addItem( "Empty" );
	std::vector<string> types;
	GuiUtilities::list_GUI(types);
	std::vector<string>::const_iterator it;
	for ( it=types.begin(); it!=types.end(); it++ ) {
		this->m_ui->cmbRequestArgumentType->addItem( (*it).c_str() );
	 }

	reset();
}

WidgetMethodCaller::~WidgetMethodCaller()
{
	delete this->m_ui;
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////

void WidgetMethodCaller::changeEvent(QEvent *e)
{
    QWidget::changeEvent(e);
    switch (e->type()) {
    case QEvent::LanguageChange:
        m_ui->retranslateUi(this);
        break;
    default:
        break;
    }
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////

void WidgetMethodCaller::setTargetURI( const URI& uri )
{
	IWidget::setTargetURI( uri );
}

void WidgetMethodCaller::setMethodName( const string& method )
 {
	this->currentMethod = method;
	this->m_ui->cmbMethod->clear();
	this->m_ui->cmbMethod->addItem( method.c_str() );
	this->m_ui->cmbMethod->setEnabled(false);

	setupRequestArgument(NULL);
	renderResponseContent(NULL);
 }

void WidgetMethodCaller::setMethodDescription( const string& description )
 {
	this->m_ui->cmbMethod->setToolTip( description.c_str() );
 }

//////////////////////////////////////////////////////////////////////////////////////////////////////////////

WRESULT WidgetMethodCaller::reset()
 {
	IWidget::setTargetURI( URI() );
	setupRequestArgument(NULL);
	renderResponseContent(NULL);
	return WRET_OK;
 }

void WidgetMethodCaller::refreshAll() {
	reset();
 }

//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////

void WidgetMethodCaller::cmbRequestArgumentType_activated( const QString& text )
 {
	if ( this->requestArgument != NULL ) {
		if ( !this->requestArgument->isSerializableType( text.toLatin1().data() ) ) {
			this->m_ui->grpRequest->layout()->removeWidget( this->requestArgument->asQWidget() );
			delete this->requestArgument; this->requestArgument = NULL;
		 }
	 }
	if ( this->requestArgument == NULL ) {
//		this->requestArgument = GuiUtilities::create_GUI( text.toLatin1().data() );
//		this->m_ui->grpRequest->layout()->addWidget( this->requestArgument->asQWidget() );
	 }

//	this->requestArgument->asQWidget()->show();
 }

void WidgetMethodCaller::btnCall_clicked()
 {
	ISerializable* rAobj = NULL;
//	if ( this->requestArgument != NULL )
//		rAobj = this->requestArgument->clone();

	Request* request_properties = new Request( this->currentMethod, rAobj );
	Message* message = new Message(request_properties);
	message->setDestinationBus( _Bus_ANY );
	postMessageForTarget(message);
 }

//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////

void WidgetMethodCaller::setupRequestArgument( ISerializable* object )
 {
	if ( object == NULL ) {
		
		return;
	 }
//IWidgetSerializable

 }


void WidgetMethodCaller::renderResponseContent( const ISerializable* object )
 {
	if ( object == NULL ) {
		this->m_ui->lblResponseClassType->setText( tr("Empty [No Data]") );
		return;
	 }
	this->m_ui->lblResponseClassType->setText( object->getClassName() );

	if ( this->responseData != NULL ) {
		if ( !this->responseData->isSerializableType( object->getClassName() ) ) {
			this->m_ui->tabResponseContent->layout()->removeWidget( this->responseData->asQWidget() );
			delete this->responseData; this->responseData = NULL;
		 }
	 }
	if ( this->responseData == NULL ) {
//		this->responseData = GuiUtilities::create_GUI( object->getClassName() );
//		this->m_ui->tabResponseContent->layout()->addWidget( this->responseData->asQWidget() );
	 }
	if ( this->responseData != NULL ) {
		this->responseData->loadSerializable(object);
	 }
//	this->responseData->asQWidget()->show();
 }

/*
void WidgetMethodCaller::renderResponse( const wosh::Response* response, const Message& message )
 {
	WidgetMessageResponse* wResponse = new WidgetMessageResponse();
	wCaller->setTargetURI( this->getTargetURI() );
	wCaller->loadObject( response );
	wCaller->show();
 }
*/

//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////

void WidgetMethodCaller::busMessage( const Message& message, const Bus* source )
 {
	(void)source;
	if ( message.isEmpty() ) return;
	if ( !message.getContent()->isResponse() ) return;
	if ( !URI::pregMatch( this->myURI, message.getDestination() ) ) return;

	const wosh::Response* response = message.getContent()->asResponse();
	if ( response->getMethod() != this->currentMethod ) return;

	this->m_ui->lblResponseMessageID->setText( QString("%1").arg( message.getID() ) );
	this->m_ui->lblResponseTimestamp->setText( QString("%1").arg( message.getTimestampAsString().c_str() ) );

	if ( WSUCCEEDED(response->getReturnValue()) )
		this->m_ui->lblResponseReturnValue->setText( QString("Succeeded. [%1]").arg( response->getReturnValue() ) );
	else
		this->m_ui->lblResponseReturnValue->setText( QString("FAILED. [%1]").arg( response->getReturnValue() ) );

	renderResponseContent( response->getData() );
	this->m_ui->tabWidget->setCurrentIndex(1);
 }


//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////

 }; // namespace gui
}; // namespace wosh
